﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;
using System.Text;
using Abp.Linq.Extensions;
using System.Threading.Tasks;
using System.Data.Entity;
using Abp.AutoMapper;
using MyCompanyName.AbpZeroTemplate.Prm.Project.Dto;
using Abp.Application.Services.Dto;
using MyCompanyName.AbpZeroTemplate.Prm.Authorization;
using MyCompanyName.AbpZeroTemplate.Prm.System;

namespace MyCompanyName.AbpZeroTemplate.Prm.Project
{
    public class ProjectAppService : AbpZeroTemplateAppServiceBase, IProjectAppService
    {
        private readonly ProjectManager projectManager;
        private readonly OperationLogManager operationLogManager;
        ///private readonly PermissionService permissionService;

        public ProjectAppService(ProjectManager _projectManager, OperationLogManager _operationLogManager)
        {
            //permissionService = _permissionService;
            projectManager = _projectManager;
            operationLogManager = _operationLogManager;
        }
        public async Task<Abp.Application.Services.Dto.PagedResultOutput<Dto.ProjectOutPut>> GetAll(Dto.GetProjectInPut input)
        {
            //long userId = 0;
            //if (AbpSession.UserId.HasValue)
            //{
            //    userId = (long)AbpSession.UserId;
            //}
            //permissionService.HasPermission(userId, ProjectFunctions.项目成本编辑);
            var query = projectManager.projectRepository.GetAll();

            var projectCount = await query.CountAsync();
            var projects = await query
                .OrderBy(input.Sorting)
                .PageBy(input)
                .ToListAsync();

            var projectListDtos = projects.MapTo<List<ProjectOutPut>>();

            return new PagedResultOutput<ProjectOutPut>(
                projectCount,
                projectListDtos
                );
        }

        /// <summary>
        /// 创建项目
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task CreateProject(CreateProjectInPut input)
        {
            var model = input.MapTo<ProjectInfo>();
            model.PlanStartDate = new DateTime(1990, 1, 1);
            model.ActualStartDate = new DateTime(1990, 1, 1);
            model.ActualEndDate = new DateTime(1990, 1, 1);
            model.Status = Status.准备;
            model.TeamCommentStatus = CommentStatus.草稿;
            model.PrmCommentStatus = CommentStatus.草稿;
            var id = await projectManager.projectRepository.InsertAndGetIdAsync(model);
            await operationLogManager.Create(id, "项目创建", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(input));
        }

        /// <summary>
        /// 编辑项目成本
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task EditCost(EditCostInput input)
        {
            var project = await projectManager.projectRepository.GetAsync(input.Id);
            project.ActualCost = input.ActualCost;
            project.ActualWorkCost = input.ActualWorkCost;
            project.TargetWorkCost = input.TargetWorkCost;
            project.ActualOutPut = input.ActualOutPut;
            project.ActualMaterialCost = input.ActualMaterialCost;
            project.TargetCost = input.TargetCost;
            project.TargetOutPut = input.TargetOutPut;
            project.TargetMaterialCost = input.TargetMaterialCost;
            await operationLogManager.Create(input.Id, "项目成本编辑", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(input));
        }

        /// <summary>
        /// 根据ID获取项目
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ProjectOutPut> Get(int id)
        {
            var project = await projectManager.projectRepository.GetAsync(id);
            var model = project.MapTo<ProjectOutPut>();
            decimal planProgress = (decimal)(DateTime.Now - project.PlanStartDate).Days / (decimal)(project.PlanEndDate - project.PlanStartDate).Days;
            model.PlanProgress = planProgress < 0 ? 0 : planProgress;

            string sTime = "----";
            string eTime = "----";
            if (project.ProjectProgress.Count() > 0)
            {
                var lastProgress = project.ProjectProgress.OrderByDescending(x => x.Id).FirstOrDefault();
                decimal actualProgress = (decimal)(DateTime.Now - lastProgress.ActualStartTime).Days / (decimal)(lastProgress.ActualEndTime - lastProgress.ActualStartTime).Days;
                model.ActualProgress = actualProgress < 0 ? 0 : actualProgress;
                sTime = lastProgress.ActualStartTime.ToString("yyyy-MM-dd");
                sTime = lastProgress.ActualEndTime.ToString("yyyy-MM-dd");
            }
            model.ActualEndDate = eTime;
            model.ActualStartDate = sTime;
            return model;
        }


        /// <summary>
        /// 设置项目进展
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task CreateProjectProgress(CreateProjectProgressInput input)
        {
            var model = input.MapTo<ProjectProgress>();

            await projectManager.SetProjectProgress(model);
            await operationLogManager.Create(input.ProjectId, "项目进展编辑", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(input));
        }

        /// <summary>
        /// 编辑项目信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task EditProject(EditProjectInPut input)
        {
            var project = await projectManager.projectRepository.GetAsync(input.Id);
            project.ProjectNo = input.ProjectNo;
            project.ProductNo = input.ProductNo;
            project.Customer = input.Customer;
            project.RdCenter = input.RdCenter;
            project.QualityStandard = input.QualityStandard;
            project.ProjectNature = input.ProjectNature;
            project.TargetWorkCost = input.TargetWorkCost;
            project.TargetOutPut = input.TargetOutPut;
            project.PlanStartDate = input.PlanStartDate;
            project.ProjectName = input.ProjectName;
            project.Address = input.Address;
            project.CustomeCode = input.CustomeCode;
            project.Lab = input.Lab;
            project.TaskType = input.TaskType;
            project.TargetEndDate = input.TargetEndDate;
            project.TargetCost = input.TargetCost;
            project.TargetMaterialCost = input.TargetMaterialCost;
            project.PlanEndDate = input.PlanEndDate;
            project.Remark = input.Remark;
            await operationLogManager.Create(input.Id, "项目编辑", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(input));
        }


        public async Task SetProjectTeam(CreateProjectTeamInPut input)
        {
            await projectManager.SetProjectTeam(input.ProjectId, input.RoleId, input.Users);

            await operationLogManager.Create(input.ProjectId, "项目成员编辑", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(input));
        }



        /// <summary>
        /// 项目团队
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public List<ProjectTeamOutPut> GetProjectTeam(int projectId)
        {
            if (projectId == 0)
                throw new Abp.UI.UserFriendlyException("系统提示", "projectId不能为零");

            List<ProjectTeamOutPut> outPuts = new List<ProjectTeamOutPut>();
            var project = projectManager.projectRepository.GetAll().Include("ProjectTeam").Where(x => x.Id == projectId).SingleOrDefault();
            var groups = project.ProjectTeam.GroupBy(x => x.ProjectRoleId).Select(x => x.Key);
            foreach (var roleId in groups)
            {
                var role = projectManager.projectRoleInfoRepository.Get(roleId);
                var teams = project.ProjectTeam.Where(x => x.ProjectRoleId == roleId).Select(m => new KeyValuePair<int, long>(m.Id, m.UserId));

                outPuts.Add(new ProjectTeamOutPut()
                {
                    RoleName = role.RoleName,
                    Teams = teams.Select(x =>
                        new KeyValuePair<int, string>(
                            x.Key,
                            UserManager.Users.Where(m => m.Id == x.Value).FirstOrDefault().Surname)
                            ).ToList()
                });
            }
            return outPuts;
        }

        /// <summary>
        /// 移除团队成员
        /// </summary>
        /// <param name="projectRoleId"></param>
        /// <returns></returns>
        public async Task RemoveProjectTeam(int projectRoleId, int projectId)
        {
            await projectManager.projectTeamRepository.DeleteAsync(projectRoleId);
            await operationLogManager.Create(projectId, "项目成员编辑", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(new { ProjectRoleId = projectRoleId, ProjectId = projectId }));
        }


        /// <summary>
        /// 得到最新的项目进度
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public async Task<GetProgressOutPut> GetLastProgressOutPut(int projectId)
        {
            GetProgressOutPut outPut = new Dto.GetProgressOutPut();
            var progress = await projectManager.projectProgressRepository.GetAll().Where(x => x.ProjectId == projectId).OrderByDescending(x => x.Id).FirstOrDefaultAsync();
            if (progress != null)
            {
                outPut.Status = progress.Status.ToString();
                outPut.Note = progress.Note;
                outPut.Task = progress.Task;
                outPut.ProgressRate = progress.ProgressRate;
                outPut.ActualStartTime = progress.ActualStartTime.ToString("yyyy-MM-dd");
                outPut.ActualEndTime = progress.ActualEndTime.ToString("yyyy-MM-dd");
            }
            return outPut;
        }

        /// <summary>
        /// 获取所有进度
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public List<GetProgressOutPut> GetProgressAll(int projectId)
        {
            var res = projectManager.projectProgressRepository.GetAll().Where(x => x.ProjectId == projectId).ToList().Select(x =>
                new GetProgressOutPut()
                {
                    ActualEndTime = x.ActualEndTime.ToString("yyyy-MM-dd"),
                    ActualStartTime = x.ActualStartTime.ToString("yyyy-MM-dd"),
                    Note = x.Note,
                    ProgressRate = x.ProgressRate,
                    Status = x.Status.ToString(),
                    Task = x.Task
                }).ToList();
            return res;
        }


        /// <summary>
        /// 成员评价
        /// </summary>
        public List<GetTeamCommentOutPut> GetTeamComment(int projectId)
        {
            List<GetTeamCommentOutPut> result = new List<GetTeamCommentOutPut>();
            //需要写成员评价的角色
            var manPlanRoles = projectManager.projectRoleInfoRepository.GetAll().Where(x => x.IsHumanWork).ToList();
            //需要写成员评价的团队成员
            var ids = manPlanRoles.Select(m => m.Id);
            var teams = projectManager.projectTeamRepository.GetAll().Where(x => ids.Contains(x.ProjectRoleId) && x.ProjectId == projectId).ToList();
            foreach (var t in teams)
            {
                var user = UserManager.Users.Where(x => x.Id == t.UserId).SingleOrDefault();
                var role = manPlanRoles.Where(x => x.Id == t.ProjectRoleId).SingleOrDefault();
                var comment = projectManager.teamCommentRepository.GetAll().Where(x => x.ProjectId == projectId && x.UserId == t.UserId && x.ProjectRoleId == t.ProjectRoleId).SingleOrDefault();
                var outPut = new GetTeamCommentOutPut()
                {
                    ProjectRoleId = t.ProjectRoleId,
                    UserId = t.UserId,
                    UserName = user.Surname + user.Name,
                    RoleName = role.RoleName,
                    Score = 1,
                    Content = string.Empty
                };
                if (comment != null)
                {
                    outPut.Id = comment.Id;
                    outPut.Score = comment.Score;
                    outPut.Content = comment.Content;
                }
                result.Add(outPut);
            }
            return result;
        }

        /// <summary>
        /// 编辑团队评价
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public Task UpdateTeamComment(List<EditTeamCommentInPut> input)
        {
            throw new NotImplementedException();
        }



        public List<GetOperationLogOutPut> GetOperationLog(int projectId)
        {
            var all = operationLogManager.operationLogRepository.GetAll().Where(x => x.HostId == projectId && x.Operation == HostOperation.项目);
            var model = all.MapTo<List<GetOperationLogOutPut>>();
            return model;
        }
    }
}
